
#include "land.h"

static Vector3f NormalTerrain(int i, int j)
{
    Vector3f AB,CD,N;
	float temp;
    Vector3f A = {(float)i-1,(float)((Texture_GetPixel(heightmapTex,i-1,j) >> 16) / 16), (float)(j)};
    Vector3f B = {(float)i+1,((float)(Texture_GetPixel(heightmapTex,i+1,j) >> 16) / 16), (float)(j)};
    Vector3f C = {(float)i,((float)(Texture_GetPixel(heightmapTex,i,j+1) >> 16) / 16), (float)(j+1)};
    Vector3f D = {(float)i,((float)(Texture_GetPixel(heightmapTex,i,j-1) >> 16) / 16), (float)(j-1)};
    Vector3f_Sub(&AB,&B,&A);
    Vector3f_Sub(&CD,&D,&C);
    Vector3f_Cross(&N,&CD,&AB);
	return N;
}

void Land_Init(const char heightmapFilename[], const char textureFilename[])
{
	int i,j, index;
	float temp;
	float textureScale = 1;
	unsigned int* indexArray;
	Vector3f normal, position;
	Type32 element;
	
	landTex =  Texture_LoadTexture(textureFilename,TRUE);
	heightmapTex = Texture_FlipSurface(IMG_Load(heightmapFilename));

	width = heightmapTex->w;
	height = heightmapTex->h;
	grass = (Grass*) malloc(sizeof(Grass) * width * height);
	waterTex  = Texture_LoadTexture("Water.png",TRUE);
	VBO_Init(&vbo, (VBO_MEMBERS)(VBO_MEMBERS_VERTEX | VBO_MEMBERS_NORMAL | VBO_MEMBERS_COLOR | VBO_MEMBERS_TEXCOORD), height * width * 2, 3, 4, 2, 0);

	for (j = 1; j < (heightmapTex->h - 1); j++)
	{
		for (i = 0; i < (heightmapTex->w); i++)
		{

			index = (i * 6) + (j * (heightmapTex->w)* 6);

			normal = NormalTerrain(i,j);
			vbo.normal[index] = normal.x;
			vbo.normal[index + 1] = normal.y;
			vbo.normal[index + 2] = normal.z;

			temp = (float)(Texture_GetPixel(heightmapTex,i,j) >> 16) / 8;
			Vector3f_Init(&position,i,temp,j);
			vbo.vertex[index] = position.x;
			vbo.vertex[index + 1] = position.y;
			vbo.vertex[index + 2] = position.z;
			
			position.x += (float)((rand() % 10) - 10) / 10;
			position.y += (float)((rand() % 10) - 10) / 10;
			position.z += (float)((rand() % 10) - 10) / 10;

			Grass_Init(&grass[i + (j - 1) * heightmapTex->w],position,normal,(GRASS_TYPE)((int)(temp / 32 * 5)));

			normal = NormalTerrain(i,j + 1);
			vbo.normal[index + 3] = normal.x;
			vbo.normal[index + 4] = normal.y;
			vbo.normal[index + 5] = normal.z;

			temp = (float)(Texture_GetPixel(heightmapTex,i,j + 1) >> 16) / 8 ;
			Vector3f_Init(&position,i,temp,j+1);
			vbo.vertex[index + 3] = position.x;
			vbo.vertex[index + 4] = position.y;
			vbo.vertex[index + 5] = position.z;
		}
	}

	for (i = 0; i < heightmapTex->w; i++)
	{
		for (j = 0; j < heightmapTex->h ; j++)
		{
			index = (i * 8) + (j * (heightmapTex->w)* 8);
			vbo.color[index + 0] = 1;
			vbo.color[index + 1] = 1;
			vbo.color[index + 2] = 1;
			vbo.color[index + 3] = 1;
			vbo.color[index + 4] = 1;
			vbo.color[index + 5] = 1;
			vbo.color[index + 6] = 1;
			vbo.color[index + 7] = 1;
		}
	}

	for (i = 0; i < heightmapTex->w; i++)
	{
		for (j = 0; j < heightmapTex->h ; j++)
		{
			index = (i * 4) + (j * (heightmapTex->w)* 4);
			vbo.texCoord[index + 0] = (float)i / heightmapTex->w * textureScale;
			vbo.texCoord[index + 1] = (float)j / heightmapTex->h * textureScale;
			vbo.texCoord[index + 2] = (float)i / heightmapTex->w * textureScale;
			vbo.texCoord[index + 3] = (float)(j + 1) / heightmapTex->h * textureScale;
			vbo.texCoord[index + 4] = (float)(i + 1) / heightmapTex->w * textureScale;
			vbo.texCoord[index + 5] = (float)j / heightmapTex->h * textureScale;
			vbo.texCoord[index + 6] = (float)(i + 1) / heightmapTex->w * textureScale;
			vbo.texCoord[index + 7] = (float)(j + 1) / heightmapTex->h * textureScale;
		}
	}

	VBO_Update(&vbo,vbo.members);

	SDL_FreeSurface(heightmapTex);
}

void Land_Draw(const Camera* camera, float elapsed)
{
	int i, index = 0;
	Sprite water;
	Vector3f posWater = {0,12,0};
	Vector3f r;
	Camera waterCam;
	Color waterColor = {255,255,255,128};
	const float ambiant=0.2;
	const float diffus=1.0;
	const float spec=0.2;
	float lenght;
	GLfloat LightAmbient[]  = { 0,0,ambiant,1.f};
	GLfloat LightDiffuse[]  = {diffus,diffus,diffus, 1.0f};
	GLfloat LightSpecular[]  = { spec, spec, spec, 1.0f};
	GLfloat LightPosition[] = {256, 120, 512, 1.0f};

	glEnable(GL_TEXTURE_2D);
	glEnable(GL_FOG);  

	glBindTexture(GL_TEXTURE_2D,landTex);

    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel (GL_SMOOTH);

    glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);
    glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);
    glLightfv(GL_LIGHT1, GL_SPECULAR, LightSpecular);
    glLightfv(GL_LIGHT1, GL_POSITION, LightPosition);
	glEnable(GL_LIGHT1);
	glEnable(GL_LIGHTING);
    
	glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ) ;
    glEnable( GL_COLOR_MATERIAL );
	
	glPushMatrix();
	for (i = 0; i < height; i++)
	{
		VBO_Draw(&vbo,vbo.members,GL_TRIANGLE_STRIP,index,width * 2);
		index+= width * 2;
	}
	glPopMatrix();
	glDisable(GL_LIGHTING);
    glDisable(GL_LIGHT0);
	/*
	glDisable(GL_FOG);
	glDisable(GL_DEPTH_TEST);
	glPushMatrix();
	for (i = 0; i < width * (height - 10); i+=1)
	{	
		Vector3f_Sub(&r,&grass[i].position,&camera->position);
		lenght = Vector3f_Length(&r);
		if (lenght < 50 && (i % 4 == 1))
		{
			grass[i].sprite->color.a = 255 - (lenght / 200 * 255);
			Grass_Draw(&grass[i],camera);
		}
		else if ((lenght < 100) && (i % 8 == 1))
		{
			grass[i].sprite->color.a = 255 - (lenght / 200 * 255);
			Grass_Draw(&grass[i],camera);
		}
		else if ((lenght < 150) && (i % 16 == 1))
		{
			grass[i].sprite->color.a = 255 - (lenght / 200 * 255);
			Grass_Draw(&grass[i],camera);
		}
		else if ((lenght < 200) && (i % 32 == 1))
		{
			grass[i].sprite->color.a = 255 - (lenght / 200 * 255);
			Grass_Draw(&grass[i],camera);
		}
	}
	glPopMatrix();
	*/
	glEnable(GL_DEPTH_TEST);
	Camera_Init(&waterCam);
	waterCam.phi = -90;
	waterCam.theta = 0;
	Sprite_InitFromTextureId(&water,waterTex,&posWater,&waterColor,0,90);
	water.height = 10;
	water.width = 10;
	glPushMatrix();
	
	elapsed /= 50;
	glTranslatef(256,0,256);
	glScalef(256,1,256);
	glDisable(GL_CULL_FACE);
	Sprite_Draw(&water,&waterCam,1.0f);
	glEnable(GL_CULL_FACE);
	glPopMatrix();
}

void Land_Destoy()
{

}
